package com.lpf.grpc;

import com.lpf.generated.proto.*;
import io.grpc.stub.StreamObserver;

import java.util.UUID;

/**
 * 功能描述：
 *
 * @author: lpf
 * @date: 2019/6/21 17:09
 * @version: 1.0
 */
public class StudentServiceImpl extends StudentServiceGrpc.StudentServiceImplBase {

    /**
     * 功能描述：简单请求
     *
     * @param request          客户端发过来的对象
     * @param responseObserver 用于向客户端返回结果的对象
     * @return void
     * @author lpf
     * @since 2019-06-21 17:14:47
     */
    @Override
    public void getRealNameByUserName(MyRequest request, StreamObserver<MyResponse> responseObserver) {
        System.out.println("接收到客户端信息：" + request.getUsername());

        responseObserver.onNext(MyResponse.newBuilder().setRealname("张三").build());//将结果返回客户端
        responseObserver.onCompleted();//标识这个方法调用结束，只能调用一次

        //responseObserver.onError();//出问题时调用
    }

    /**
     * 功能描述：服务端流式

     * @param request
     * @param responseObserver
     * @return void
     * @author lpf
     * @since 2019-11-24 13:06:31
     **/
    @Override
    public void getStudentsByAge(StudentRequest request, StreamObserver<StudentResponse> responseObserver) {
        System.out.println("接收到客户端信息：" + request.getAge());

        // 流式其实就是向客户端一个一个的返回数据
        responseObserver.onNext(StudentResponse.newBuilder().setName("张三").setAge(20).setCity("北京").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("李四").setAge(30).setCity("天津").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("王五").setAge(40).setCity("成都").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("赵六").setAge(50).setCity("深圳").build());

        // 标识服务端的处理已经完毕了
        responseObserver.onCompleted();
    }

    /**
     * 功能描述：客户端流式

     * @param responseObserver
     * @return io.grpc.stub.StreamObserver<com.lpf.generated.proto.StudentRequest>
     * @author lpf
     * @since 2019-11-24 13:23:06
     **/
    @Override
    public StreamObserver<StudentRequest> getStudentsWrapperByAges(StreamObserver<StudentResponseList> responseObserver) {
        // 以下整个都表示客户端的信息
        // 当对应的事件产生的时候，相应的回调方法就会执行
        return new StreamObserver<StudentRequest>() {
            // 接收客户端发过来的请求
            // 请求到来时调用一次（接收到一个message），再来一次在调用一次（再接收到一个message）
            @Override
            public void onNext(StudentRequest value) {
                System.out.println("onNext: " + value.getAge());
            }

            // 出错时调用
            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            // 当客户端传输数据完成后，客户端会有一个 onCompleted 事件，服务端会感知到这个事件，然后调用 onCompleted 方法，返回数据给客户端
            // 客户端消息全部传输完成之后
            @Override
            public void onCompleted() {
                StudentResponse studentResponse1 = StudentResponse.newBuilder().setName("张三").setAge(20).setCity("北京").build();
                StudentResponse studentResponse2 = StudentResponse.newBuilder().setName("李四").setAge(30).setCity("天津").build();

                StudentResponseList studentResponseList = StudentResponseList.newBuilder()//
                                                                            .addStudentResponse(studentResponse1)//
                                                                            .addStudentResponse(studentResponse2)//
                                                                            .build();
                // 服务器返回数据给客户端使用responseObserver对象
                responseObserver.onNext(studentResponseList);
                // 表示服务器端执行结束
                responseObserver.onCompleted();
            }
        };
    }

    // 客户端到服务端的流 和 服务端到客户端的流 是两个独立的流
    @Override
    public StreamObserver<StreamRequest> biTalk(StreamObserver<StreamResponse> responseObserver) {
        return new StreamObserver<StreamRequest>() {
            @Override
            public void onNext(StreamRequest value) {
                System.out.println(value.getRequestInfo());
                responseObserver.onNext(StreamResponse.newBuilder().setResponseInfo(UUID.randomUUID().toString()).build());
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            // 一个流关闭 另一个流也关闭，单独开一个流没有意义
            @Override
            public void onCompleted() {
                responseObserver.onCompleted();
            }
        };
    }
}
